#! /usr/bin/env python
#-*- encoding:utf-8 -*-
#文件名:stock.py
"""Test code

Description:________
"""
__version__  = "0.1"
__date__     = "2007-08-15 22:15:27"
__author__   = "yetist <yetist@gmail.com> "
__license__  = "Licensed under the GPL v2, see the file LICENSE in this tarball."
__copyright__= "Copyright (C) 2007 by yetist <yetist@gmail.com>."
#=================================================================================#
import sys,os
import urllib
import libxml2
import gtk
from gtk import glade
import gobject
import thread

class Parser:
    url1 = "http://wap.618618.cn/stock/wap12/hangqing.jsp?code=%s&type=1"
    url2 = "http://wap.618618.cn/stock/wap12/hangqing.jsp?code=%s&type=2"
    def __init__(self):
        self.ret = { "error": False, "name": "", "time": "" }
        self.imgtype = ['min', 'daily', 'weekly', 'monthly']
        self.cat1 = ["xianjia", "junjia", "zhangdie", "zhangfu", "xianshou", "zongshou", "jinge", "zuoshou", "kaipan", "zuigao", "zuidi"]
        self.cat_cn1 = ["现价", "均价", "涨跌", "涨幅", "现手", "总手", "金额(万)", "昨收", "开盘", "最高", "最低"]
        self.cat2 = ["out5", "out4", "out3", "out2", "out1", "in1", "in2", "in3", "in4", "in5"]

    def get_all(self, stockid):
        self.get_hq(stockid)
        self.get_jy(stockid)
        self.get_img(stockid)

    def get_hq(self, stockid):

        url = Parser.url1 % stockid
        tmp1 = self._get_(stockid, url)

        if not self.ret["error"]:
            self.ret["name"] = tmp1[0].split("(")[0]
            self.ret["stockid"] = stockid
            self.ret["time"] = tmp1[1][-8:]
                    
            for i in range(11):
                if self.cat1[i] == "jinge":
                    self.ret[self.cat1[i]] = tmp1[i+3].split("：")[1].replace("万", "")
                else:
                    self.ret[self.cat1[i]] = tmp1[i+3].split("：")[1]

    def get_jy(self, stockid):
        url = Parser.url2 % stockid
        tmp1 = self._get_(stockid, url)

        if not self.ret["error"]:
            for i in range(10):
                self.ret[self.cat2[i]] = {}
                self.ret[self.cat2[i]]["jiage"]= tmp1[3*i+4].split("：")[1]
                self.ret[self.cat2[i]]["xianshou"]= tmp1[3*i+5].split("：")[1]

    def get_img(self, stockid):
        #返回图片url地址


        if stockid[0] in ["5", "6"]:
            prefix = "sh"
        elif stockid[0] in ["0"]:
            prefix = "sz"

        for i in self.imgtype:
            self.ret["url_" + i] = "http://image.sinajs.cn/newchart/%s/n/%s%s.gif" % (i, prefix, stockid)

    def _get_(self, stockid, url):
        handle = urllib.urlopen(url)
        buf = handle.read()
        data = libxml2.parseMemory(buf, len(buf))

        for i in data.get_children():
            if i.name == "p":
                p = i

        tmp=[]
        for i in p.get_children():
            if i.name == "anchor":
                break
            if i.name == "text":
                line = i.content.replace("\n","").replace("\t","")
                if line != "":
                    tmp.append(line)

        if len(tmp) < 14:
            self.ret["error"] = True
        return tmp

class UI:
    def __init__(self):
        self.cache_path = "/tmp/stock_cache"
        self.parser = Parser()
        self.xml = glade.XML(os.path.join(os.getcwd(), "stock.glade"))
        self.win = self.xml.get_widget("main_window")
        self.win.set_position(gtk.WIN_POS_CENTER_ALWAYS)
        self.win.set_icon_from_file(os.path.join(os.getcwd(), "stock.jpeg"))
        self.win.connect("destroy", gtk.main_quit)
        tv = self.xml.get_widget("treeview")
        tv.connect("row-activated", self.row_activated)
        tv.hide()
        a = ["代码", "名称"]
        a.extend(self.parser.cat_cn1)
        for i in range(len(a)):
            renderer = gtk.CellRendererText()
            column = gtk.TreeViewColumn(a[i], renderer, text=i)
            column.set_property("reorderable", True)
            column.set_sort_column_id(i)
            tv.append_column(column)
        self.win.show_all()

        if not os.path.isdir(self.cache_path):
            os.mkdir(self.cache_path)

        combo = self.xml.get_widget("combox_entry")
        combo.connect("changed", self.on_search)

        btn = self.xml.get_widget("btn_search")
        btn.connect("clicked", self.on_search)

        menu_quit = self.xml.get_widget("menuitem_quit")
        menu_quit.connect("activate", gtk.main_quit)

        menu_item = self.xml.get_widget("menuitem_info")
        menu_item.connect("toggled", self.on_view_change)
        menu_item = self.xml.get_widget("menuitem_list")
        menu_item.connect("toggled", self.on_view_change)
        menu_item = self.xml.get_widget("menuitem_about")
        menu_item.connect("activate", self.on_about)

        configfile_path = os.path.join(os.getenv("HOME"), ".pystock")
        combo = self.xml.get_widget("combox_entry")
        entry = self.xml.get_widget("entry_stockid")
        if os.path.isfile(configfile_path):
            fp = open( configfile_path)
            data = fp.readlines()
            data.sort()
            data.reverse()
            fp.close()
            for i in data:
                id = i[:6]
                if id != "" and len(id) == 6 and id.isdigit():
                    entry.set_text(id)
        else:
            entry.set_text("600000")

    def on_about(self, menu):
        def destroy(widget, a, b):
            widget.hide()
        dlg = self.xml.get_widget("aboutdialog")
        dlg.connect("response", destroy, dlg)
        dlg.show()

    def on_view_change (self, menu):
        main_box = self.xml.get_widget("main_vbox")
        tv = self.xml.get_widget("treeview")
        if menu.name == "menuitem_info":
            for i in ("hbox2", "hbox15", "hseparator1", "hbox1"):
                box = self.xml.get_widget(i)
                box.show()
            tv = self.xml.get_widget("treeview")
            tv.hide()
        else:
            for i in ("hbox2", "hbox15", "hseparator1", "hbox1"):
                box = self.xml.get_widget(i)
                box.hide()
            tv = self.xml.get_widget("treeview")
            self.refresh_list_view()
            tv.show()

    def row_activated (self, tv, path, column):
        model = tv.get_model()
        iter = model.get_iter(path)
        id = model.get_value(iter, 0)
        entry = self.xml.get_widget("entry_stockid")
        entry.set_text(str(id))
        menu_item = self.xml.get_widget("menuitem_info")
        menu_item.activate()

    def on_search(self, btn):
        combo = self.xml.get_widget("combox_entry")
        model = combo.get_model()
        entry = self.xml.get_widget("entry_stockid")

        iter = model.get_iter_first()
        id = entry.get_text()
        if id != "" and len(id) == 6 and id.isdigit():
            iter = model.get_iter_first()
            if model.get_value(iter,0) == id:
                model.remove(iter)
            else:
                while model.iter_next(iter):
                    iter = model.iter_next(iter)
                    if model.get_value(iter,0) == id:
                        model.remove(iter)
                        break
            combo.insert_text(0,id)
            notebook = self.xml.get_widget("notebook")
            notebook.set_current_page(0)
            thread.start_new_thread(self.refresh_hq, (id,))
            thread.start_new_thread(self.refresh_jy, (id,))
            thread.start_new_thread(self.refresh_img, (id,))

    def refresh_list_view(self):
        def sort_func( treemodel, iter1, iter2, c):
            val1 = treemodel.get_value(iter1, c)
            val2 = treemodel.get_value(iter2, c)
            if val1.endswith("%"):
                val1 = val1[:-1]
            if val2.endswith("%"):
                val2 = val2[:-1]
            if float(val1) - float(val2) > 0:
                return 1
            elif float(val1) - float(val2) == 0:
                return 0
            else:
                return -1
        combo = self.xml.get_widget("combox_entry")
        model = combo.get_model()

        iter = model.get_iter_first()
        val = model.get_value(iter,0)
        if val != "":
            id=[val]
        while model.iter_next(iter):
            iter = model.iter_next(iter)
            id.append (model.get_value(iter,0))

        model = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING,
        gobject.TYPE_STRING,
        gobject.TYPE_STRING,
        gobject.TYPE_STRING,
        gobject.TYPE_STRING,
        gobject.TYPE_STRING,
        gobject.TYPE_STRING,
        gobject.TYPE_STRING,
        gobject.TYPE_STRING,
        gobject.TYPE_STRING,
        gobject.TYPE_STRING,
        gobject.TYPE_STRING)
        tv = self.xml.get_widget("treeview")
        for i in id:
            self.parser.get_hq(i)
            if self.parser.ret["error"]:
                self.parser.ret["error"] = False
                continue
            iter = model.append(None, None)
            model.set_value(iter, 0, self.parser.ret["stockid"])
            model.set_value(iter, 1, self.parser.ret["name"])
            for n in range(len(self.parser.cat1)):
                model.set_value(iter, n+2, self.parser.ret[self.parser.cat1[n]])
                model.set_sort_func(n+2, sort_func, n+2)
        tv.set_model(model)

    def refresh_hq(self, stockid):
        #刷新行情
        self.parser.get_hq(stockid)
        if self.parser.ret["error"]:
            gtk.gdk.threads_enter()
            dlg = gtk.MessageDialog(parent=self.win, flags=gtk.DIALOG_MODAL, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK, message_format="错误! 股票代码%s不存在!" % stockid)
            if dlg.run() == gtk.RESPONSE_OK:
                self.parser.ret["error"] = False
                dlg.destroy()
            gtk.gdk.threads_leave()
            return
        sizegrp = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)

        label = self.xml.get_widget("label_name")
        label.set_markup("""<span size="large">%s</span>""" % self.parser.ret["name"])
        label = self.xml.get_widget("label_id")
        label.set_text(self.parser.ret["stockid"])
        label = self.xml.get_widget("label_time")
        label.set_text(self.parser.ret["time"])
        #刷新行情
        for i in self.parser.cat1:
            if i == "xianjia":
                for n in range(2):
                    label = self.xml.get_widget("label_"+i+str(n))
                    sizegrp.add_widget(label)
                    txt = """<span foreground="red" weight="bold">%s</span>""" % self.parser.ret[i]
                    label.set_markup(txt)
                continue
            label = self.xml.get_widget("label_" + i)
            sizegrp.add_widget(label)
            label.set_text(self.parser.ret[i])

    def refresh_jy(self, stockid):
        #刷新交易
        sizegrp = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
        self.parser.get_jy(stockid)
        if self.parser.ret["error"]:
            gtk.gdk.threads_enter()
            dlg = gtk.MessageDialog(parent=self.win, flags=gtk.DIALOG_MODAL, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK, message_format="错误! 股票代码%s不存在!" % stockid)
            if dlg.run() == gtk.RESPONSE_OK:
                self.parser.ret["error"] = False
                dlg.destroy()
            gtk.gdk.threads_leave()
            return
        for i in self.parser.cat2:
            for n in self.parser.ret[i].keys():
                widget_name = "label_%s_%s" % (i, n)
                label = self.xml.get_widget(widget_name)
                sizegrp.add_widget(label)
                label.set_text(self.parser.ret[i][n])

    def refresh_img(self, stockid):
        #刷新图片
        self.parser.get_img(stockid)
        notebook = self.xml.get_widget("notebook")
        for i in range(4):
            imgtype = self.parser.imgtype[i]
            url = self.parser.ret["url_" + imgtype]
            file_name =  os.path.join(self.cache_path, stockid + imgtype + ".gif")
            os.system("wget -q -O %s %s" % (file_name, url))
            img = self.xml.get_widget("img_" + imgtype)
            img.set_from_file(file_name)

    def main(self):
        gtk.gdk.threads_init()
        gtk.main()
        
if __name__=="__main__":
    a=UI()
    a.main()
